/*
 * Copyright (c)  2008 Sebastien Tremblay
 *
 * id3-tag-builder - gui.Application.java
 *
 * All source and documentation is copyrighted by Sebastien Tremblay
 * (seb at ryders dot net) and made available under the Apache License 2.0.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * $Id: Application.java 33 2010-04-02 07:47:55Z ryders $
 */
package com.empireone.id3tagbuilder.gui;

import com.empireone.id3tagbuilder.Id3TagBuilder;
import com.empireone.id3tagbuilder.Id3TagBuilderException;
import com.empireone.id3tagbuilder.classes.Format;
import com.empireone.id3tagbuilder.classes.Path;
import com.empireone.id3tagbuilder.gui.tree.CheckTreeManager;
import com.empireone.id3tagbuilder.settings.ApplicationSettings;
import com.empireone.id3tagbuilder.threads.StatusUpdateListener;
import java.awt.Dimension;
import java.util.Locale;
import java.util.ResourceBundle;
import java.util.Vector;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.UIManager;
import javax.swing.UIManager.LookAndFeelInfo;

/**
 * The <code>Application</code> class is the gui (Swing) interface to
 * interact id3-tag-builder.
 *
 * @author Sebastien Tremblay
 */
public class Application extends javax.swing.JFrame implements StatusUpdateListener {

    private ResourceBundle labels;
    private Locale appLocale;
    private Id3TagBuilder app;
    private CheckTreeManager checkTreeManager;

    /** Creates new form Application
     * @param settings
     */
    public Application(ApplicationSettings settings) {

        loadUI(settings.getLocale(), settings.getWinManager());

        app = new Id3TagBuilder(settings, this);

        initComponents();

        checkTreeManager = new CheckTreeManager(ltr_paths);

        status(MsgType.HALTED);

        positionWindow();
    }

    // <editor-fold defaultstate="collapsed" desc=" Application Configuration, UI and Locale settings ">
    /**
     * 
     * @param value
     */
    private void setAppLocale(Locale value) {
        appLocale = value;
        labels = ResourceBundle.getBundle(getClass().getName(), appLocale);
    }

    /**
     * 
     */
    private void loadUI(Locale locale, String winMgr) {

        try {
            setAppLocale(locale);
            for (LookAndFeelInfo lafi : UIManager.getInstalledLookAndFeels()) {
                if (winMgr.equalsIgnoreCase(lafi.getName())) {
                    javax.swing.UIManager.setLookAndFeel(lafi.getClassName());
                    break;
                }
            }
        } catch (Exception ex) {
            Logger.getLogger(Application.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    /**
     * 
     */
    private void positionWindow() {
        Dimension d = getToolkit().getScreenSize();
        setLocation(d.width / 2 - this.getWidth() / 2, d.height / 2 - this.getHeight() / 2);
    }
    // </editor-fold>

    /**
     * This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        cbo_formats = new javax.swing.JComboBox();
        prb_execProgress = new javax.swing.JProgressBar();
        scp_treeView = new javax.swing.JScrollPane();
        ltr_paths = new javax.swing.JTree();
        btn_none = new javax.swing.JButton();
        btn_toggle = new javax.swing.JButton();
        btn_run = new javax.swing.JButton();
        btn_select = new javax.swing.JButton();
        scp_output = new javax.swing.JScrollPane();
        txt_output = new javax.swing.JTextArea();
        mnu_main = new javax.swing.JMenuBar();
        mnu_file = new javax.swing.JMenu();
        mnu_fileRun = new javax.swing.JMenuItem();
        mnu_fileSep1 = new javax.swing.JSeparator();
        mnu_fileQuit = new javax.swing.JMenuItem();
        mnu_settings = new javax.swing.JMenu();
        mnu_settingsID3v1 = new javax.swing.JCheckBoxMenuItem();
        mnu_settingsID3v2 = new javax.swing.JCheckBoxMenuItem();
        mnu_settingsEmbedArt = new javax.swing.JCheckBoxMenuItem();
        mnu_settingsCleanup = new javax.swing.JCheckBoxMenuItem();
        mnu_settingsSep1 = new javax.swing.JSeparator();
        mnu_maintainDb = new javax.swing.JCheckBoxMenuItem();
        jSeparator1 = new javax.swing.JSeparator();
        mnu_settingsShowDetails = new javax.swing.JCheckBoxMenuItem();
        mnu_help = new javax.swing.JMenu();
        mnu_helpQuick = new javax.swing.JMenuItem();
        mnu_Sep1 = new javax.swing.JSeparator();
        mnu_helpAbout = new javax.swing.JMenuItem();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setTitle("Seb's RegExpr ID3 Builder");
        setMinimumSize(new java.awt.Dimension(400, 600));
        addWindowListener(new java.awt.event.WindowAdapter() {
            public void windowClosing(java.awt.event.WindowEvent evt) {
                formWindowClosing(evt);
            }
        });

        cbo_formats.setModel(new javax.swing.DefaultComboBoxModel(app.getSettings().getFormats()));
        cbo_formats.setBorder(null);

        prb_execProgress.setValue(99);
        prb_execProgress.setAlignmentX(0.0F);
        prb_execProgress.setAlignmentY(0.0F);

        ltr_paths.setModel(new com.empireone.id3tagbuilder.gui.tree.TreeViewModel(app.getSettings().getPaths()));
        scp_treeView.setViewportView(ltr_paths);

        btn_none.setText(labels.getString("btn-select_none")); // NOI18N
        btn_none.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btn_noneActionPerformed(evt);
            }
        });

        btn_toggle.setText(labels.getString("btn-select_toggle")); // NOI18N
        btn_toggle.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btn_toggleActionPerformed(evt);
            }
        });

        btn_run.setText(labels.getString("btn-run")); // NOI18N
        btn_run.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                mnu_fileRunActionPerformed(evt);
            }
        });

        btn_select.setText(labels.getString("btn-select")); // NOI18N
        btn_select.setEnabled(app.getSettings().getMaintainMusicDb());

        txt_output.setColumns(20);
        txt_output.setEditable(false);
        txt_output.setFont(new java.awt.Font("Verdana", 0, 10));
        txt_output.setRows(5);
        scp_output.setViewportView(txt_output);

        mnu_file.setText(labels.getString("menu-file")); // NOI18N

        mnu_fileRun.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_R, java.awt.event.InputEvent.ALT_MASK));
        mnu_fileRun.setText(labels.getString("menu-file-run")); // NOI18N
        mnu_fileRun.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                mnu_fileRunActionPerformed(evt);
            }
        });
        mnu_file.add(mnu_fileRun);
        mnu_file.add(mnu_fileSep1);

        mnu_fileQuit.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_Q, java.awt.event.InputEvent.ALT_MASK));
        mnu_fileQuit.setText(labels.getString("menu-file-quit")); // NOI18N
        mnu_fileQuit.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                mnu_fileQuitActionPerformed(evt);
            }
        });
        mnu_file.add(mnu_fileQuit);

        mnu_main.add(mnu_file);

        mnu_settings.setText(labels.getString("menu-settings")); // NOI18N

        mnu_settingsID3v1.setSelected(app.getSettings().getWriteId3v1());
        mnu_settingsID3v1.setText(labels.getString("menu-settings-write_v1")); // NOI18N
        mnu_settingsID3v1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                mnu_settingsID3v1ActionPerformed(evt);
            }
        });
        mnu_settings.add(mnu_settingsID3v1);

        mnu_settingsID3v2.setSelected(app.getSettings().getWriteId3v2());
        mnu_settingsID3v2.setText(labels.getString("menu-settings-write_v2")); // NOI18N
        mnu_settingsID3v2.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                mnu_settingsID3v2ActionPerformed(evt);
            }
        });
        mnu_settings.add(mnu_settingsID3v2);

        mnu_settingsEmbedArt.setSelected(app.getSettings().getEmbedArt());
        mnu_settingsEmbedArt.setText(labels.getString("menu-settings-embed_art")); // NOI18N
        mnu_settingsEmbedArt.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                mnu_settingsEmbedArtActionPerformed(evt);
            }
        });
        mnu_settings.add(mnu_settingsEmbedArt);

        mnu_settingsCleanup.setSelected(app.getSettings().getCleanupTags());
        mnu_settingsCleanup.setText(labels.getString("menu-settings-cleanup_tags")); // NOI18N
        mnu_settingsCleanup.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                mnu_settingsCleanupActionPerformed(evt);
            }
        });
        mnu_settings.add(mnu_settingsCleanup);
        mnu_settings.add(mnu_settingsSep1);

        mnu_maintainDb.setSelected(app.getSettings().getMaintainMusicDb());
        mnu_maintainDb.setText(labels.getString("menu-settings-maintain_db")); // NOI18N
        mnu_maintainDb.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                mnu_maintainDbActionPerformed(evt);
            }
        });
        mnu_settings.add(mnu_maintainDb);
        mnu_settings.add(jSeparator1);

        mnu_settingsShowDetails.setSelected(app.getSettings().getDisplayDetails());
        mnu_settingsShowDetails.setText(labels.getString("menu-settings-show_details")); // NOI18N
        mnu_settingsShowDetails.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                mnu_settingsShowDetailsActionPerformed(evt);
            }
        });
        mnu_settings.add(mnu_settingsShowDetails);

        mnu_main.add(mnu_settings);

        mnu_help.setText(labels.getString("menu-help")); // NOI18N

        mnu_helpQuick.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_F1, 0));
        mnu_helpQuick.setText(labels.getString("menu-help-quick")); // NOI18N
        mnu_help.add(mnu_helpQuick);
        mnu_help.add(mnu_Sep1);

        mnu_helpAbout.setText(labels.getString("menu-help-about")); // NOI18N
        mnu_helpAbout.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                mnu_helpAboutActionPerformed(evt);
            }
        });
        mnu_help.add(mnu_helpAbout);

        mnu_main.add(mnu_help);

        setJMenuBar(mnu_main);

        org.jdesktop.layout.GroupLayout layout = new org.jdesktop.layout.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(layout.createSequentialGroup()
                .addContainerGap()
                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                    .add(scp_output, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 386, Short.MAX_VALUE)
                    .add(scp_treeView, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 386, Short.MAX_VALUE)
                    .add(org.jdesktop.layout.GroupLayout.TRAILING, layout.createSequentialGroup()
                        .add(cbo_formats, 0, 328, Short.MAX_VALUE)
                        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                        .add(btn_select))
                    .add(layout.createSequentialGroup()
                        .add(btn_none)
                        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                        .add(btn_toggle)
                        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED, 244, Short.MAX_VALUE)
                        .add(btn_run))
                    .add(org.jdesktop.layout.GroupLayout.TRAILING, prb_execProgress, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 386, Short.MAX_VALUE))
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(layout.createSequentialGroup()
                .addContainerGap()
                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
                    .add(btn_select)
                    .add(cbo_formats, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 20, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(scp_treeView, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 269, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
                    .add(btn_none)
                    .add(btn_toggle)
                    .add(btn_run))
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(scp_output, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 199, Short.MAX_VALUE)
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(prb_execProgress, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                .addContainerGap())
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void mnu_settingsCleanupActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_mnu_settingsCleanupActionPerformed
        app.getSettings().setCleanupTags(mnu_settingsCleanup.isSelected());
        app.getSettings().save();
    }//GEN-LAST:event_mnu_settingsCleanupActionPerformed

    private void mnu_settingsEmbedArtActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_mnu_settingsEmbedArtActionPerformed
        app.getSettings().setEmbedArt(mnu_settingsEmbedArt.isSelected());
        app.getSettings().save();
    }//GEN-LAST:event_mnu_settingsEmbedArtActionPerformed

    private void mnu_settingsID3v2ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_mnu_settingsID3v2ActionPerformed
        app.getSettings().setWriteId3v2(mnu_settingsID3v2.isSelected());
        this.mnu_settingsEmbedArt.setEnabled(this.mnu_settingsID3v2.isSelected());
        app.getSettings().save();
    }//GEN-LAST:event_mnu_settingsID3v2ActionPerformed

    private void mnu_settingsID3v1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_mnu_settingsID3v1ActionPerformed
        app.getSettings().setWriteId3v1(mnu_settingsID3v1.isSelected());
        app.getSettings().save();
    }//GEN-LAST:event_mnu_settingsID3v1ActionPerformed

    private void mnu_helpAboutActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_mnu_helpAboutActionPerformed
        /*java.awt.EventQueue.invokeLater(new Runnable() {
        public void run() {
        //new About().setVisible(true);
        }
        });*/
        //java.awt.EventQueue.invokeLater(new Runnable() {
        //   public void run() {
        //}
        //});
    }//GEN-LAST:event_mnu_helpAboutActionPerformed

    private void mnu_maintainDbActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_mnu_maintainDbActionPerformed
        app.getSettings().setMaintainMusicDb(mnu_maintainDb.isSelected());
        btn_select.setEnabled(mnu_maintainDb.isSelected());
        app.getSettings().save();
}//GEN-LAST:event_mnu_maintainDbActionPerformed

    private void formWindowClosing(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_formWindowClosing
        app.getSettings().save();
    }//GEN-LAST:event_formWindowClosing

    private void btn_toggleActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btn_toggleActionPerformed
        checkTreeManager.selectToggle();
    }//GEN-LAST:event_btn_toggleActionPerformed

    private void btn_noneActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btn_noneActionPerformed
        checkTreeManager.selectNone();
    }//GEN-LAST:event_btn_noneActionPerformed

    private void mnu_fileQuitActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_mnu_fileQuitActionPerformed
        app.getSettings().save();
        dispose();
        System.exit(0);
    }//GEN-LAST:event_mnu_fileQuitActionPerformed

    private void mnu_fileRunActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_mnu_fileRunActionPerformed

        if (!app.isWorking()) {
            Vector<Path> paths = checkTreeManager.getSelectedPaths();
            if (paths.size() > 0) {
                try {
                    app.run((Format) cbo_formats.getSelectedItem(), paths);
                } catch (Id3TagBuilderException ex) {
                    Logger.getLogger(Application.class.getName()).log(Level.SEVERE, null, ex);
                    mnu_fileQuitActionPerformed(evt);
                }
            }
        } else {
            app.abort();
        }

    }//GEN-LAST:event_mnu_fileRunActionPerformed

private void mnu_settingsShowDetailsActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_mnu_settingsShowDetailsActionPerformed
    app.getSettings().setDisplayDetails(mnu_settingsShowDetails.isSelected());
    scp_output.setVisible(mnu_settingsShowDetails.isSelected());
    app.getSettings().save();
}//GEN-LAST:event_mnu_settingsShowDetailsActionPerformed
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton btn_none;
    private javax.swing.JButton btn_run;
    private javax.swing.JButton btn_select;
    private javax.swing.JButton btn_toggle;
    private javax.swing.JComboBox cbo_formats;
    private javax.swing.JSeparator jSeparator1;
    private javax.swing.JTree ltr_paths;
    private javax.swing.JSeparator mnu_Sep1;
    private javax.swing.JMenu mnu_file;
    private javax.swing.JMenuItem mnu_fileQuit;
    private javax.swing.JMenuItem mnu_fileRun;
    private javax.swing.JSeparator mnu_fileSep1;
    private javax.swing.JMenu mnu_help;
    private javax.swing.JMenuItem mnu_helpAbout;
    private javax.swing.JMenuItem mnu_helpQuick;
    private javax.swing.JMenuBar mnu_main;
    private javax.swing.JCheckBoxMenuItem mnu_maintainDb;
    private javax.swing.JMenu mnu_settings;
    private javax.swing.JCheckBoxMenuItem mnu_settingsCleanup;
    private javax.swing.JCheckBoxMenuItem mnu_settingsEmbedArt;
    private javax.swing.JCheckBoxMenuItem mnu_settingsID3v1;
    private javax.swing.JCheckBoxMenuItem mnu_settingsID3v2;
    private javax.swing.JSeparator mnu_settingsSep1;
    private javax.swing.JCheckBoxMenuItem mnu_settingsShowDetails;
    private javax.swing.JProgressBar prb_execProgress;
    private javax.swing.JScrollPane scp_output;
    private javax.swing.JScrollPane scp_treeView;
    private javax.swing.JTextArea txt_output;
    // End of variables declaration//GEN-END:variables

    /**
     *
     * @param value
     */
    @Override
    public void updateWorkload(int value) {
        prb_execProgress.setMaximum(prb_execProgress.getMaximum() + value);
    }

    /**
     *
     * @param value
     */
    @Override
    public void updateProgress(int value) {
        prb_execProgress.setIndeterminate(false);
        prb_execProgress.setValue(prb_execProgress.getValue() + value);
        prb_execProgress.setToolTipText((float) prb_execProgress.getValue() / (float) prb_execProgress.getMaximum() * 100 + "%");
    }

    /**
     *
     * @param type
     */
    @Override
    public void status(MsgType type) {

        switch (type) {
            case STARTED:
                prb_execProgress.setIndeterminate(true);
                prb_execProgress.setValue(0);
                prb_execProgress.setMaximum(0);
                btn_run.setText(labels.getString("btn-cancel"));
                mnu_fileRun.setText(labels.getString("btn-cancel"));

                break;

            case SCHEDULED:
                prb_execProgress.setIndeterminate(false);
                break;

            case COMPLETED:
            case HALTED:
                btn_run.setText(labels.getString("btn-run"));
                mnu_fileRun.setText(labels.getString("btn-run"));

                prb_execProgress.setIndeterminate(false);
                prb_execProgress.setValue(0);
                prb_execProgress.setMaximum(1);

                break;
        }
    }

    /**
     *
     * @param type
     * @param str
     */
    @Override
    public void status(MsgType type, String str) {
        status(type);

        txt_output.append(str + "\n");
        txt_output.setCaretPosition(txt_output.getDocument().getLength());

        switch (type) {
            case JOB_COMPLETED:
                System.out.print("FINISHED:" + str.split("|")[4]);
                break;

        }
    }
}
